package stars;

import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import old.coordinate.CoordinateModel;

import com.jme3.asset.AssetManager;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;

import controller.AbstractController;
import controller.IController;

import stars.enums.EStarDistribution;
import stars.enums.EStarMods;
import stars.enums.EStarSystemType;
import stars.enums.EStarType;
import stars.enums.StarColors;
import stars.enums.StarDistributions;
import stars.enums.StarParameters;
import stars.enums.StarSystemDistributions;
import stars.enums.StarSystemNames;
import stars.enums.StarSystemParameters;
import stars.starGroups.StarGroupController;
import stars.starGroups.StarGroupModel;
import stars.starGroups.StarGroupView;
import stars.starSystems.StarSystemController;
import stars.starSystems.StarSystemGenerator;
import stars.starSystems.StarSystemLayoutBuilder;
import stars.starSystems.StarSystemModel;
import stars.starSystems.StarSystemModelBuilder;
import stars.starSystems.StarSystemOrbitBuilder;
import stars.starSystems.StarSystemView;
import stars.starSystems.StarSystemViewBuilder;
import utilities.Key;
import utilities.MVCMaker;
import model.universe.MHabitable;
import eventManager.EventManager;
import galaxies.enums.EGalaxyAge;
import galaxies.enums.EarthLike;
import gameAppLayer.GameSettings;
import gameAppLayer.XMLData;
import gameAppLayer.enums.Constants;
import habitables.HabitableController;
import habitables.HabitableModelBuilder;
import habitables.HabitableViewBuilder;
import habitables.HabitableGenerator;
import habitables.HabitableView;


/*
 * Encapsulates rules for star system formation
 */
public class BatchSystemBuilder {
	
	private static final Logger logger = Logger.getLogger(BatchSystemBuilder.class.getName());
	
	StarSystemParameters sysParams;
	StarSystemDistributions sysDists;
	StarSystemNames sysNames;
	StarParameters starParams;
	StarDistributions starDists;
	StarColors starColors;
	EarthLike earthLike;
	//Add remaining habitable inputs
	
	public BatchSystemBuilder() {}
	
	public void buildRandomSystem(GameSettings settings, AssetManager assets, EventManager events, 
			XMLData xmlData, ArrayList<Integer> location, String galRef) {
		sysParams = xmlData.getStarSystemParameters();
		sysDists = xmlData.getStarSystemDistributions();
		sysNames = xmlData.getStarSystemNames();
		
		starParams = xmlData.getStarParameters();
		starDists = xmlData.getStarDistributions();
		starColors = xmlData.getStarColors();
		
		earthLike = xmlData.getEarthLike();
		
		ArrayList<IController> controllers = new ArrayList<IController>();
		
		//1) Determine random system layout
		StarSystemLayoutBuilder layoutBuilder = new StarSystemLayoutBuilder();
		String layout = layoutBuilder.chooseLayout(sysDists);
		
		//2) Build system object
		StarSystemGenerator sysGenerator = new StarSystemGenerator(settings, assets, events, sysDists, sysNames); 
		StarSystemController sysController = sysGenerator.createStarSystem(location);
		controllers.add(sysController);
		StarSystemModel sysModel = sysGenerator.systemModel;
		String sysLayout = sysModel.getSystemLayout();
		
		//3) Build starGroup objects
		ArrayList<Integer> groups = sysDists.getStarGroupParams(sysLayout);
		StarGenerator starGenerator = new StarGenerator(events, assets, starParams, starColors, starDists);
		String age = settings.getGalaxyAge(galRef).toString();
		StarController starController;
		StarModel starModel;
		
		for (Integer group: groups) {
			StarGroupModel starGroupModel = new StarGroupModel();
			Key starGroupKey;
			//4) Build star objects, place in starGroup
			for (int i = 0; i < group; i++) {
				starController = starGenerator.createSingleStar(age);
				controllers.add(starController);
				starModel = starGenerator.model;
				
				starGroupModel.addStar(starModel);
			}
			
			StarGroupView starGroupView = new StarGroupView();
			StarGroupController starGroupController = new StarGroupController(events);
			MVCMaker.linkElements(starGroupModel, starGroupView, starGroupController);
			
			//5) Add starGroup to starSystem
			starGroupKey = starGroupModel.getKey();
			sysGenerator.systemModel.addStarGroup(starGroupKey);
		}		
		
		/*
		 * Note:  From here, things become more difficult.
		 * 
		 * Habitable orbit spacing can be dictated by the mass of each habitable vs. that of its neighbors.  Build from the 
		 * center of the system (starGroup) out.  The size of each preceeding habitable combined with the size of the current 
		 * one predicts the distance between them.
		 * 
		 * Must work on habitable generation algorithm before proceeding with orbit development.
		 */
		
		//6) Determine random system orbits (given starSystem)
		StarSystemOrbitBuilder sysOrbitBuilder = new StarSystemOrbitBuilder();
		sysOrbitBuilder.randomNumOrbits(sysParams, sysModel);
		
		
		
		
		
		
	}
	
	
	
	
	
	
	/*
	 * Single
	 * Binary
	 * Binary + outer single
	 * Trinary
	 */
	private int systemTypes = EStarSystemType.SYSTEM_CATEGORIES.size();
	private int singleSystemTypes = EStarSystemType.SINGLE_SYSTEMS.size();
	private int binarySystemTypes = EStarSystemType.BINARY_SYSTEMS.size();
	private int trinarySystemTypes = EStarSystemType.TRINARY_SYSTEMS.size();
	private int quadSystemTypes = EStarSystemType.QUAD_SYSTEMS.size();
	private int starTypes = EStarType.ALL_STARS.size();	
	
	//double minBinarySepAU = 3; //for orbiting binaries
	//double maxBinarySepAU = 150;
	//double minBinarySepKm = minBinarySepAU*Constants.AUtoKm;
	//double maxBinarySepKm = maxBinarySepAU*Constants.AUtoKm;
	/*
	 * Separation of orbiting binaries that leads to no stable orbits.
	 * Applies to any orbiting system configurations.  Any star singles/groups in this zone will have no planets.
	 */
	//double minBinaryDeadZoneAU = 3; 
	//double maxBinaryDeadZoneAU = 30;  
	//double minBinaryDeadZoneKm = minBinaryDeadZoneAU*Constants.AUtoKm;
	//double maxBinaryDeadZoneKm = maxBinaryDeadZoneAU*Constants.AUtoKm;
	
	//Single star orbit boundaries for orbiting habitables
	//double minHabOrbitAU = 0.05;
	//double maxHabOrbitAU = 100;
	//double minHabOrbitKm = minHabOrbitAU*Constants.AUtoKm;
	//double maxHabOrbitKm = maxHabOrbitAU*Constants.AUtoKm;
	
	double[] cumuMultiStarProbs = new double[systemTypes];	
	double[] cumuSingleSystemTypeProbs = new double[singleSystemTypes];
	double[] cumuBinarySystemTypeProbs = new double[binarySystemTypes+1];
	double[] cumuTrinarySystemTypeProbs = new double[trinarySystemTypes+1];
	double[] cumuQuadSystemTypeProbs = new double[quadSystemTypes+1];	
	double[][] cumuStarTypeProbs = new double[starTypes+1][3];
	private Random rand = new Random();	
	
	private StarGenerator starGen;
	private StarSystemGenerator starSysGen;
	private HabitableGenerator habGen;	
	
	//ArrayList<CStar> stars = new ArrayList<CStar>();
	
	public ArrayList<StarSystemModel> systemModels = new ArrayList<StarSystemModel>();
	public ArrayList<StarSystemView> systemViews = new ArrayList<StarSystemView>();
	public ArrayList<StarSystemController> systemControllers = new ArrayList<StarSystemController>();
	
	//each system can have multiple stars
	public ArrayList<ArrayList<StarModel>> starModels = new ArrayList<ArrayList<StarModel>>();
	public ArrayList<ArrayList<StarView>> starViews = new ArrayList<ArrayList<StarView>>();
	public ArrayList<ArrayList<StarController>> starControllers = new ArrayList<ArrayList<StarController>>();
	
	//each system can have multiple starGroups
	public ArrayList<ArrayList<StarGroupModel>> starGroupModels = new ArrayList<ArrayList<StarGroupModel>>();
	public ArrayList<ArrayList<StarGroupView>> starGroupViews = new ArrayList<ArrayList<StarGroupView>>();
	public ArrayList<ArrayList<StarGroupController>> starGroupControllers = new ArrayList<ArrayList<StarGroupController>>();
	
	//each starGroup can have multiple habitables
	public ArrayList<ArrayList<ArrayList<MHabitable>>> habModels = new ArrayList<ArrayList<ArrayList<MHabitable>>>();
	public ArrayList<ArrayList<ArrayList<HabitableView>>> habViews = new ArrayList<ArrayList<ArrayList<HabitableView>>>();
	public ArrayList<ArrayList<ArrayList<HabitableController>>> habControllers = new ArrayList<ArrayList<ArrayList<HabitableController>>>();
	
	//Star systems
	//------------------------------------------------------
	private StarSystemModelBuilder systemModelFact;
	private StarSystemModel systemModel;	
	private StarSystemViewBuilder systemViewFact;
	private StarSystemView systemView;	
	private StarSystemController systemController;
	//------------------------------------------------------
	
	//Star groups
	//------------------------------------------------------
	private StarGroupModel starGroupModel;
	private StarGroupView starGroupView;
	private StarGroupController starGroupController;	
	//------------------------------------------------------
	
	
	//Stars
	//------------------------------------------------------
	private StarModelBuilder starModelFact;
	private StarModel starModel;
	private StarViewBuilder starViewFact;
	private StarView starView;
	private StarController starController;	
	//------------------------------------------------------
	
	
	//Habitables
	//------------------------------------------------------
	private HabitableModelBuilder habModelFact;
	private MHabitable habModel;
	private HabitableViewBuilder habViewFact;
	private HabitableView habView;
	private HabitableController habController;
	//------------------------------------------------------
	
	
	//Master controller list, to be returned to calling entity
	//------------------------------------------------------
	private ArrayList<AbstractController> masterControllerList = new ArrayList<AbstractController>();	
	//------------------------------------------------------
	
	double randValue1;
	double randValue2;
	
	private GameSettings settings;
	private AssetManager assets;
	private EventManager eventManager; 
	
	private int systemNumber = 0;
	private int starNumber = 0;
	private int habNumber = 0;
	
	private EGalaxyAge age;
	
	public BatchSystemBuilder(GameSettings settings, AssetManager assets, EventManager eventManager) {
		this.settings = settings;
		this.assets = assets;
		this.eventManager = eventManager;
		this.age = settings.getGalaxyAge();
		calcStarTypeProbs();
		calcBinarySystemProbs();
		calcTrinarySystemProbs();
		calcQuadSystemProbs();
		//starSysGen = new StarSystemGenerator(settings, assets);
		//habGen = new HabitableGenerator(settings, assets);
		//starGen = new StarGenerator();
		logger.log(Level.INFO, "BatchSystemBuilder: BatchSystemBuilder initialized");
	}
	
	private void calcBinarySystemProbs() {
		double value = 0.0;		
		cumuBinarySystemTypeProbs[0] += value;
		
		value += EStarSystemType.BINARY_CENTER.getProbability();		
		cumuBinarySystemTypeProbs[1] += value;
		
		value += EStarSystemType.BINARY_ORBIT.getProbability();		
		cumuBinarySystemTypeProbs[2] += value;		
	}
	
	private void calcTrinarySystemProbs() {
		double value = 0.0;		
		cumuTrinarySystemTypeProbs[0] += value;
		
		value += EStarSystemType.TRINARY_CENTER.getProbability();		
		cumuTrinarySystemTypeProbs[1] += value;
		
		value += EStarSystemType.TRINARY_BIN_CENTER_SIN_ORBIT.getProbability();		
		cumuTrinarySystemTypeProbs[2] += value;
		
		value += EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT.getProbability();
		cumuTrinarySystemTypeProbs[3] += value;
		
		value += EStarSystemType.TRINARY_ALL_ORBIT.getProbability();
		cumuTrinarySystemTypeProbs[4] += value;
	}
	
	private void calcQuadSystemProbs() {
		double value = 0.0;
		cumuQuadSystemTypeProbs[0] += value;
		
		value += EStarSystemType.QUAD_CENTER.getProbability();
		cumuQuadSystemTypeProbs[1] += value;
		
		value += EStarSystemType.QUAD_TRI_CENTER_SINGLE_ORBIT.getProbability();
		cumuQuadSystemTypeProbs[2] += value;
		
		value += EStarSystemType.QUAD_BIN_CENTER_BIN_ORBIT.getProbability();
		cumuQuadSystemTypeProbs[3] += value;
		
		value += EStarSystemType.QUAD_BIN_CENTER_SIN_ORBIT_SIN_ORBIT.getProbability();
		cumuQuadSystemTypeProbs[4] += value;
	}
	
	public ArrayList<AbstractController> createSystems(ArrayList<Vector2f> locations) {
		logger.log(Level.INFO, "BatchSystemBuilder: createSystems()");
		boolean modelCheck = buildModels(locations);
		boolean viewCheck = buildViews();
		boolean controllerCheck = buildControllers();
		boolean bindCheck = bindElements(); //MVCMaker
		
		boolean listCheck = createMasterControllerList();
		
		return masterControllerList;
	}
	
	private boolean createMasterControllerList() {
		masterControllerList.addAll(systemControllers);
		
		for (int i = 0; i < starControllers.size(); i++) {
			masterControllerList.addAll(starControllers.get(i));			
		}
		
		for (int i = 0; i < starGroupControllers.size(); i++) {
			masterControllerList.addAll(starGroupControllers.get(i));
		}
		
		for (int i = 0; i < habControllers.size(); i++) {
			for (int j = 0; j < habControllers.get(i).size(); j++) {
				masterControllerList.addAll(habControllers.get(i).get(j));
			}
		}
		
		return true;
	}
	
	
	private boolean buildModels(ArrayList<Vector2f> locations) {
		boolean systemCheck = buildStarSystemModels(locations);
		boolean starCheck = buildStarModels();
		boolean groupCheck = buildStarGroupModels();
				
		boolean habCheck = buildHabitableModels(); //?
		
		return true;
	}
	
	private boolean buildViews() {
		boolean systemCheck = buildStarSystemViews(systemModels);
		boolean starCheck = buildStarViews(starModels);
		boolean groupCheck = buildStarGroupViews(starGroupModels); //?
		
		boolean habCheck = buildHabitableViews(); //?
		
		return true;
	}
	
	private boolean buildControllers() {
		boolean systemCheck = buildStarSystemControllers(systemModels);
		boolean starCheck = buildStarControllers(starModels);
		boolean groupCheck = buildStarGroupControllers(starGroupModels);
		
		boolean habCheck = buildHabitableControllers(); //?
		
		return true;
	}
	
	private boolean bindElements() {
		//NOTE:  All models currently have just one view associated with them
		
		//Bind starSystems
		for (int i = 0; i < systemModels.size(); i++) {
			MVCMaker.linkElements(systemModels.get(i), systemViews.get(i), systemControllers.get(i));
		}
		
		//Bind stars
		for (int j = 0; j < starModels.size(); j++) {			
			for (int k = 0; k < starModels.get(j).size(); k++) {				
				MVCMaker.linkElements(starModels.get(j).get(k), starViews.get(j).get(k), starControllers.get(j).get(k));
			}			
		}
		
		//Bind starGroups
		for (int j = 0; j < starGroupModels.size(); j++) {			
			for (int k = 0; k < starGroupModels.get(j).size(); k++) {				
				MVCMaker.linkElements(starGroupModels.get(j).get(k), starGroupViews.get(j).get(k), starGroupControllers.get(j).get(k));
			}
		}
		
		//Bind habitables
		
				
		
		return true;
	}
	
	
	private boolean buildStarSystemModels(ArrayList<Vector2f> locations) {
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarSystemModels()");
		
		systemModelFact = new StarSystemModelBuilder(settings);
		
		for (Vector2f location: locations) {
			systemModel = systemModelFact.createModel(location);
			systemModels.add(systemModel);
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarSystemModels() COMPLETE");
		return true;
	}
	
	private boolean buildStarModels() {
		starModelFact = new StarModelBuilder();
		
		StarModel tempStar;
		EStarType starType;
		EStarSystemType systemType;
		
		double temperature = 0.0;
		
		for (int i = 0; i < systemModels.size(); i++) {			
			starModels.add(i, new ArrayList<StarModel>());
			
			//Set random type for the first star
			starType = randomType(age);			
			temperature = randomTemperature(starType);
			
			//Build first star
			tempStar = starModelFact.createMStar(temperature, starType);			
			starModels.get(i).add(tempStar);
			
			//fill in cumulative probability vector for number of stars based on type of first star
			calcMultiStarProbs(starType);	
			
			systemType = determineSystemType();
			systemModels.get(i).setSystemLayout(systemType);
			
			//Use systemType to build correct number of stars			
			//System.out.println("L283 Number of stars: " + systemType.getNumStars());		
			for (int j = 0; j < systemType.getNumStars()-1; j++) {
				temperature = randomTemperature(starType);
				tempStar = starModelFact.createMStar(temperature, starType);						
				starModels.get(i).add(j, tempStar);
			}
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarModels() COMPLETE");
		return true;
	}
	
	private boolean buildStarGroupModels() {
		
		for (int m = 0; m < systemModels.size(); m++) {		
			ArrayList<StarModel> stars = starModels.get(m);
			
			//for (MStar star: thisSystem) {
			//	System.out.println("L307 Star type: " + star.getType().toString());
			//	System.out.println("L308 Star mass: " + star.getMass());
			//}
			
			//Sort stars by mass.		
			ArrayList<StarModel> sortedSystem = new ArrayList<StarModel>();
			
			for (StarModel star: stars) {
				sortedSystem.add(star);
			}
			
			double mass = 0;
			double tempMass;
			for (int j = 0; j < stars.size()-1; j++) {
				mass = sortedSystem.get(j).getMass();
				for (int i = j+1; i < stars.size(); i++) {
					tempMass = sortedSystem.get(i).getMass();
					if (tempMass > mass) {
						sortedSystem.add(j, sortedSystem.get(i));
						sortedSystem.remove(i+1);
						mass = tempMass;
					}
				}
			}
			//System.out.println("Sorted system size: " +sortedSystem.size());
			
			stars.clear();
			stars.addAll(sortedSystem);
			
//			for (MStar star: stars) {
//				System.out.println("L331 Star type: " + star.getType().toString());
//				System.out.println("L332 Star mass: " + star.getMass());
//			}
			
			//Note:  Not accepting any return data here, using class variables as inputs
			//Set star orbits, groupings
			//System.out.println("BatchSystemBuilder, creating starGroupOrbits!");
			ArrayList<StarGroupModel> starGroups = createStarGroupOrbits(systemModels.get(m).getSystemLayout(), stars);			
			starGroupModels.add(m, starGroups);
		}		
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarGroupModels() COMPLETE");
		return true;
	}
	
	private boolean buildHabitableModels() {
		habModelFact = new HabitableModelBuilder();
		
		
		//Habitables			
		//-----------------------------------------			
		//Based on stars in system and their locations, determine initial system gas giant orbits
		
		//Use age of universe and stars in system to "age" giants and their orbits
		
		//Based on final system gas giant orbits, create giants
		//NOTE:  There may be zero giants.
		
		//Fill in rocky/icy planets
		
		
		return true;
	}
	
	private EStarSystemType determineSystemType() {
		randValue1 = rand.nextDouble();
		
		//defaults to SINGLE
		EStarSystemType type = EStarSystemType.SINGLE;
		
		//Determine if system should be a single, binary, trinary, or quad (plus which type), then create additional stars
		if (randValue1 < cumuMultiStarProbs[1]) {
			//binary, add just one more star
			randValue2 = rand.nextDouble();
			
			if (randValue2 < cumuBinarySystemTypeProbs[1]) {
				type = EStarSystemType.BINARY_CENTER;
			}
			else {
				type = EStarSystemType.BINARY_ORBIT;
			}
		}
		else if ((randValue1 < cumuMultiStarProbs[2]) && (randValue1 >= cumuMultiStarProbs[1])) {
			//trinary, add two more stars
			randValue2 = rand.nextDouble();
			
			if (randValue2 < cumuTrinarySystemTypeProbs[1]) {
				type = EStarSystemType.TRINARY_CENTER;
			}
			else if ((randValue2 < cumuTrinarySystemTypeProbs[2]) && (randValue2 >= cumuTrinarySystemTypeProbs[1])) {
				type = EStarSystemType.TRINARY_BIN_CENTER_SIN_ORBIT;
			}
			else if ((randValue2 < cumuTrinarySystemTypeProbs[3]) && (randValue2 >= cumuTrinarySystemTypeProbs[2])) {
				type = EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT;
			}
			else if ((randValue2 < cumuTrinarySystemTypeProbs[4]) && (randValue2 >= cumuTrinarySystemTypeProbs[3])) {
				type = EStarSystemType.TRINARY_ALL_ORBIT;
			}
		}
		else if ((randValue1 < cumuMultiStarProbs[3]) && (randValue1 >= cumuMultiStarProbs[2])) {
			//quad, add three more stars
			randValue2 = rand.nextDouble();
			
			if (randValue2 < cumuQuadSystemTypeProbs[1]) {
				type = EStarSystemType.QUAD_CENTER;
			}
			else if ((randValue2 < cumuQuadSystemTypeProbs[2]) && (randValue2 >= cumuQuadSystemTypeProbs[1])) {
				type = EStarSystemType.QUAD_TRI_CENTER_SINGLE_ORBIT;
			}
			else if ((randValue2 < cumuQuadSystemTypeProbs[3]) && (randValue2 >= cumuQuadSystemTypeProbs[2])) {
				type = EStarSystemType.QUAD_BIN_CENTER_BIN_ORBIT;
			}
			else if ((randValue2 < cumuQuadSystemTypeProbs[4]) && (randValue2 >= cumuQuadSystemTypeProbs[3])) {
				type = EStarSystemType.QUAD_BIN_CENTER_SIN_ORBIT_SIN_ORBIT;
			}				
		}
		else {
			type = EStarSystemType.SINGLE;
		}			
		
		//////////////For testing only
		//type = EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT;
		//////////////
		
		return type;		
	}
	
	
	
	private boolean buildStarSystemViews(ArrayList<StarSystemModel> systems) {
		systemViewFact = new StarSystemViewBuilder();
		
		for (StarSystemModel systemModel: systems) {		
			systemView = systemViewFact.createView(systemModel, assets);
			systemViews.add(systemView);
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarSystemViews() COMPLETE");
		return true;
	}
	
	private boolean buildStarViews(ArrayList<ArrayList<StarModel>> starModels) {
		starViewFact = new StarViewBuilder();	
		
		//Iterate over systems
		for (int i = 0; i < starModels.size(); i++) {	
			starViews.add(i, new ArrayList<StarView>());
			
			//Iterate over individual stars
			for (int j = 0; j < starModels.get(i).size(); j++) {
				starView = starViewFact.createView(starModels.get(i).get(j), assets);			
				starViews.get(i).add(j, starView);
			}
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarViews() COMPLETE");
		return true;
	}
	
	private boolean buildStarGroupViews(ArrayList<ArrayList<StarGroupModel>> starGroups) {
		
		for (int i = 0; i < starGroups.size(); i++) {			
			starGroupViews.add(i, new ArrayList<StarGroupView>());
			
			for (int j = 0; j < starGroups.get(i).size(); j++) {
				starGroupView = new StarGroupView();
				starGroupViews.get(i).add(j, starGroupView);
			}
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarGroupViews() COMPLETE");
		return true;
	}
	
	private boolean buildHabitableViews() {
		habViewFact = new HabitableViewBuilder();
		
		
		return true;
	}
	
	
	
	private boolean buildStarSystemControllers(ArrayList<StarSystemModel> systems) {
		for (StarSystemModel systemModel: systems) {		
			systemController = new StarSystemController(eventManager);
			systemControllers.add(systemController);
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarSystemControllers() COMPLETE");
		return true;
	}
	
	private boolean buildStarControllers(ArrayList<ArrayList<StarModel>> starModels) {
		for (int i = 0; i < starModels.size(); i++) {
			starControllers.add(i, new ArrayList<StarController>());
			
			for (int j = 0; j < starModels.get(i).size(); j++) {			
				starController = new StarController(eventManager);
				starControllers.get(i).add(j, starController);
			}
		}
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarControllers() COMPLETE");
		return true;
	}
	
	private boolean buildStarGroupControllers(ArrayList<ArrayList<StarGroupModel>> starGroups) {
		for (int i = 0; i < starGroups.size(); i++) {
			starGroupControllers.add(i, new ArrayList<StarGroupController>());
			
			for (int j = 0; j < starGroups.get(i).size(); j++) {
				starGroupController = new StarGroupController(eventManager);
				starGroupControllers.get(i).add(starGroupController);
			}
		}		
		
		logger.log(Level.INFO, "BatchSystemBuilder: buildStarGroupControllers() COMPLETE");
		return true;
	}
	
	private boolean buildHabitableControllers() {
		
		return true;
	}
	
	
	
	
	//private void fakeMethod() {	
		
		
		
		//Star systems
		//-------------------------------------------
		//systemModelFact = new FMStarSystem(settings);
		//systemViewFact = new FVStarSystem();		
		
		//for (Vector3f location: locations) {
			//systemModel = systemModelFact.createModel(location);
			//systemView = systemViewFact.createView(systemModel, assets);
			//systemController = new CStarSystem(eventManager);
			
			//systemModels.add(systemModel);
			//systemViews.add(systemView);
			//systemControllers.add(systemController);
			
			
			
			/*System.out.print("X: "+ location.x + "  ");
			System.out.print("Y: "+ location.y + "  ");
			System.out.println("Z: "+ location.z);*/			
		//}
		//-------------------------------------------
		
		
		//Build stars, arrange stars, build habitables
		//-------------------------------------------
		//starModelFact = new FMStar();
		//starViewFact = new FVStar();		
		//MStar firstStar;
		//EStarType type;
		//MStarSystem targetSystem;
		
		
		
//		for (MStarSystem system: systemModels) {
			
			//starModels.add(systemNumber, new ArrayList<MStar>());
			//starViews.add(systemNumber, new ArrayList<VStar>());
			//starControllers.add(systemNumber, new ArrayList<CStar>());
			
			//Set random type for the first star
			//type = randomType(age);
			
			/*
			 * Generate first star in system.  This updates the class variables 
			 * starModel, View and Controller with a new star every time it is called.
			 */
			//buildStar(type);			
			//firstStar = starModel;			
			
			//add first star to lists immediately
			//starModels.get(systemNumber).add(starModel);
			//starViews.get(systemNumber).add(starView);
			//starControllers.get(systemNumber).add(starController);
			
			//fill in cumulative probability vector for number of stars based on type of first star
			//calcMultiStarProbs(starModel.getType());			
			
			
			
			
			
			
			//Use number in systemLayout to build correct number of stars
			//EStarSystemType systemLayout = system.getSystemLayout();
			//System.out.println("L331 Number of stars: " + systemLayout.getNumStars());		
			//for (int j = 0; j < systemLayout.getNumStars()-1; j++) {
				//buildStar(settings.getGalaxyAge());
						
				//starModels.get(systemNumber).add(starModel);
				//starViews.get(systemNumber).add(starView);
				//starControllers.get(systemNumber).add(starController);					
			//}
			
			
//			//Figure out where star(s) go in the system.
//			//--------------------------------------
//			ArrayList<MStar> stars = starModels.get(systemNumber);
//			
//			//for (MStar star: thisSystem) {
//			//	System.out.println("L345 Star type: " + star.getType().toString());
//			//	System.out.println("L346 Star mass: " + star.getMass());
//			//}
//			
//			//Sort stars by mass.		
//			ArrayList<MStar> sortedSystem = new ArrayList<MStar>();
//			
//			for (MStar star: stars) {
//				sortedSystem.add(star);
//			}
//			
//			double mass = 0;
//			double tempMass;
//			for (int j = 0; j < stars.size()-1; j++) {
//				mass = sortedSystem.get(j).getMass();
//				for (int i = j+1; i < stars.size(); i++) {
//					tempMass = sortedSystem.get(i).getMass();
//					if (tempMass > mass) {
//						sortedSystem.add(j, sortedSystem.get(i));
//						sortedSystem.remove(i+1);
//						mass = tempMass;
//					}
//				}
//			}
//			//System.out.println("Sorted system size: " +sortedSystem.size());
//			
//			stars.clear();
//			stars.addAll(sortedSystem);
//			
//			for (MStar star: stars) {
//				System.out.println("L381 Star type: " + star.getType().toString());
//				System.out.println("L382 Star mass: " + star.getMass());
//			}
//			
//			//Note:  Not accepting any return data here, using class variables as inputs
//			//Set star orbits, groupings
//			ArrayList<MStarGroup> starGroups = createStarGroupOrbits(system, stars);
//			
//			
//			///////////////////////////////////////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//			for (MStarGroup group: starGroups) {
//				system.addStarGroup(group.getKey());
//			}
//			
//			ArrayList<ArrayList<Double>> habitableZones = setHabZones(system, starGroups);
//			
//			//Set system habitable zones based on star orbits
//			system.setHabitableZones(habitableZones);			
//			
//			for (MStar star: starModels.get(systemNumber)) {
//				System.out.println("starModels: " + star.getOrbitRadius());
//			}			
//			
//			for (MStar star: stars) {
//				System.out.println("thisSystem: " + star.getOrbitRadius());
//			}
//			//--------------------------------------
//			
//			
//			//Now have allowed orbital ranges for the solar system.
//			
//			
//			/*
//			 * Calculate snow zones for each habitable zone.  These are the areas that 
//			 * can spawn gas giants during early system formation and is the demarcation
//			 * where the early protoplanetary disk temp goes down to below ~ 150 - 170K.
//			 */
//			ArrayList<ArrayList<Double>> snowZones = new ArrayList<ArrayList<Double>>();
//			
//			//
//			for (MStarGroup starGroup: starGroups) {
//				starGroup.getSnowZoneList().set(1, starGroup.getHabZoneList().get(1));
//				snowZones.add(starGroup.getSnowZoneList());
//			}
//			
			
			
			
			
			
			
			
			
			
//			//register stars with starSystem via eventManager
//			targetSystem = systemModels.get(systemNumber);
//			for (MStar star: starModels.get(systemNumber)) {				
//				eventManager.queueEvent(new StarSystemAddStarEvent(System.currentTimeMillis(), 
//						targetSystem.getKey(), star.getKey()));				
//			}
			
			
			
			
			
			
			
			
//			System.out.println(systemNumber);
//			systemNumber++;
//		}
		//-------------------------------------------
		
		
		
		
		
		
//		return systemModels;
//	}
	
//	private ArrayList<ArrayList<Double>> calculateSnowZones(ArrayList<MStarGroup> starGroups) {
//		
////		ArrayList<Double> snowLines = new ArrayList<Double>();
////		
////		EStarSystemType systemType = system.getSystemLayout();
////		ArrayList<ArrayList<Double>> habZones = system.getHabitableZones();
//		
//		ArrayList<ArrayList<Double>> snowZones = new ArrayList<ArrayList<Double>>();
//		
//		//set outer bound of snow zone equal to outer bound of hab zone
//		for (MStarGroup starGroup: starGroups) {
//			starGroup.getSnowZoneList().set(1, starGroup.getHabZoneList().get(1));
//			snowZones.add(starGroup.getSnowZoneList());
//		}
//		
//		return snowZones;
//		
//		double luminosity = 0.0;
//		double snowRadius = 0.0;
//		double snowTemp = 160; //K		
//		double argument = 1/(4*Math.PI*Constants.BoltzmannConstant*snowTemp*snowTemp*snowTemp*snowTemp);
//		double scaleFactor = 2.244;
//		
//		if (systemType.equals(EStarSystemType.SINGLE)) {
//			//DO NOTHING.  MStarGroup takes care of this.  DELETE THIS SECTION.
//			
////			luminosity += stars.get(0).getLuminosity();
////			snowRadius = stars.get(0).getRadius() + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km				
////			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.BINARY_CENTER)) {
//			//DO NOTHING.  MStarGroup takes care of this.  DELETE THIS SECTION.
//			
////			for (MStar star: stars) {
////				luminosity += star.getLuminosity();
////			}
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(0));
////			tempSystem.add(stars.get(1));
////			double largestRadius = largestRadius(tempSystem);
////			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
////			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.BINARY_ORBIT)) {
//			
//			
//			
//			luminosity = stars.get(0).getLuminosity();
//			System.out.println("Lum: " + luminosity);
//			snowRadius = stars.get(0).getOrbitRadius() + stars.get(0).getRadius() + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km 
//			System.out.println("Snow: " + snowRadius);
//			System.out.println("Last term: " + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor);
//			snowLines.add(snowRadius);
//			
//			luminosity = stars.get(1).getLuminosity();
//			System.out.println("Lum: " + luminosity);
//			snowRadius = stars.get(1).getOrbitRadius() - stars.get(1).getRadius() - Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km 
//			System.out.println("Snow: " + snowRadius);
//			System.out.println("Last term: " + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor);
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.TRINARY_CENTER)) {
//			for (MStar star: stars) {
//				luminosity += star.getLuminosity();				
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			tempSystem.add(stars.get(2));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.TRINARY_BIN_CENTER_SIN_ORBIT)) {
//			for (int i = 0; i < 2; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			luminosity = stars.get(2).getLuminosity();
//			snowRadius = stars.get(2).getOrbitRadius() - stars.get(2).getRadius() - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT)) {
//			luminosity = stars.get(0).getLuminosity();
//			snowRadius = Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			luminosity = 0.0;
//			for (int i = 1; i < 3; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(1));
//			tempSystem.add(stars.get(2));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = stars.get(1).getOrbitRadius() - largestRadius - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.TRINARY_ALL_ORBIT)) {			
//			//1st star
//			luminosity = stars.get(0).getLuminosity();
//			snowRadius = stars.get(0).getRadius() + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//left side of 2nd star
//			luminosity = stars.get(1).getLuminosity();
//			snowRadius = stars.get(1).getOrbitRadius() - stars.get(1).getRadius() -
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//right side of 2nd star
//			snowRadius = stars.get(1).getOrbitRadius() + stars.get(1).getRadius() +
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//3rd star			
//			luminosity = stars.get(2).getLuminosity();
//			snowRadius = stars.get(2).getOrbitRadius() - stars.get(2).getRadius() -
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);			
//		}
//		else if (systemType.equals(EStarSystemType.QUAD_CENTER)) {
//			for (MStar star: stars) {
//				luminosity += star.getLuminosity();				
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			tempSystem.add(stars.get(2));
//			tempSystem.add(stars.get(3));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.QUAD_TRI_CENTER_SINGLE_ORBIT)) {
//			for (int i = 0; i < 3; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			tempSystem.add(stars.get(2));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//4th star
//			luminosity = stars.get(3).getLuminosity();
//			snowRadius = stars.get(3).getOrbitRadius() - stars.get(3).getRadius() - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);			
//		}
//		else if (systemType.equals(EStarSystemType.QUAD_BIN_CENTER_BIN_ORBIT)) {
//			for (int i = 0; i < 2; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			tempSystem.clear();
//			luminosity = 0.0;			
//			for (int i = 2; i < 4; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			
//			tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(2));
//			tempSystem.add(stars.get(3));
//			largestRadius = largestRadius(tempSystem);
//			snowRadius = stars.get(2).getOrbitRadius() - largestRadius - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		else if (systemType.equals(EStarSystemType.QUAD_BIN_CENTER_SIN_ORBIT_SIN_ORBIT)) {
//			for (int i = 0; i < 2; i++) {
//				luminosity += stars.get(i).getLuminosity();
//			}
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius = largestRadius(tempSystem);
//			snowRadius = largestRadius + Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//3rd star, left side
//			luminosity = stars.get(2).getLuminosity();
//			snowRadius = stars.get(2).getOrbitRadius() - stars.get(2).getRadius() - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//3rd star, right side
//			snowRadius = stars.get(2).getOrbitRadius() + stars.get(2).getRadius() + 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//			
//			//4th star
//			snowRadius = stars.get(3).getOrbitRadius() - stars.get(3).getRadius() - 
//				Math.sqrt(luminosity*argument)*Constants.MtoKm/scaleFactor; //km
//			snowLines.add(snowRadius);
//		}
//		
//		System.out.println("Number of snowlines: " + snowLines.size());
//		for (Double snowLine: snowLines) {
//			System.out.println("Line: " + snowLine);			
//		}
//		
//		//test for snowLines that overlap and remove them
//		boolean leftRemove = false;
//		boolean rightRemove = false;
//		if (snowLines.size() == 2) {
//			//Is snowline from center star(s) beyond snowline from out star(s)?
//			if (snowLines.get(0) > snowLines.get(1)) {
//				snowLines.clear();
//			}			
//		}
//		else if (snowLines.size() == 4) {
//			if (snowLines.get(0) > snowLines.get(1)) {
//				leftRemove = true;
//			}			
//			
//			if (snowLines.get(2) > snowLines.get(3)) {
//				rightRemove = true;
//			}
//			
//			if (leftRemove && rightRemove) {
//				snowLines.clear();
//			}
//			else if (leftRemove && !rightRemove) {
//				snowLines.remove(0);
//				snowLines.remove(0);
//				snowLines.remove(0); 
//				//^^must remove right side of center star(s), since planets don't just hang around one side!
//				//only leaves last star with a snow line.
//			}
//			else if (!leftRemove && rightRemove) {
//				snowLines.remove(1);
//				snowLines.remove(1);
//				snowLines.remove(1);
//				//^^again, must remove both side of center star.  Only leaves first star with a snow line.
//			}
//		}
//		
//		System.out.println("After removing overlapping: " + snowLines.size());
//		for (Double snowLine: snowLines) {
//			System.out.println("Line: " + snowLine);			
//		}
//		
//		//test for snowlines outside allowed habZones and remove them
//		//create endcaps for snowlines in habZones.  Call them "snowZones"
//		ArrayList<Double> garbageCollection = new ArrayList<Double>();
//		ArrayList<Double> addinCollection = new ArrayList<Double>();
//		
//		for (Double snowLine: snowLines) {
//			boolean located = false;
//			int j = 0;
//			for (ArrayList<Double> habZone: habZones) {
//				//if snowline is between any of the hab zones, keep it
//				System.out.println("j: " + j);
//				System.out.println("Left HabZone: " + habZone.get(0));
//				System.out.println("Right HabZone: " + habZone.get(1));
//				System.out.println("SnowZone: " + snowLine);
//				if ((snowLine > habZone.get(0)) && (snowLine < habZone.get(1))) {
//					located = true;					
//					if ((j==1) || (j==3)) {//(habZone.get(0) < habZone.get(1)) {
//						//on the left side of the star, so add the leftmost (further away) point as endcap
//						addinCollection.add(habZone.get(0));
//					}
//					else {						
//						//on the right side of the star, so add the rightmost (further away) point as endcap
//						addinCollection.add(habZone.get(1));
//					}
//					
//				}
//				j++;
//			}
//			
//			if (!located) {
//				System.out.println("Garbage! " + snowLine);
//				garbageCollection.add(snowLine);
//				//tempSnowLines.remove(snowLine);
//			}
//		}
//		
//		snowLines.removeAll(garbageCollection);
//		snowLines.addAll(addinCollection);
//		
//		System.out.println("After removing outside habZones: " + snowLines.size());
//		for (Double snowLine: snowLines) {
//			System.out.println("Line: " + snowLine);			
//		}
//		
//		//sort snowLine data according to distance.  Endcaps added out of order
//		//snowLines.clear();
//		
//		double distance = 0;
//		double tempDistance;
//		for (int j = 0; j < snowLines.size()-1; j++) {
//			distance = snowLines.get(j);
//			for (int i = j+1; i < snowLines.size(); i++) {
//				tempDistance = snowLines.get(i);
//				if (tempDistance < distance) {
//					snowLines.add(j, snowLines.get(i));
//					snowLines.remove(i+1);
//					distance = tempDistance;
//				}
//			}
//		}
//		
//		System.out.println("After sorting for distance: " + snowLines.size());
//		for (Double snowLine: snowLines) {
//			System.out.println("Line: " + snowLine);			
//		}
//		
//		ArrayList<ArrayList<Double>> snowZones = new ArrayList<ArrayList<Double>>();
//		int j = 0;
//		//Create snowZones out of snowLine data
//		for (int i = 0; i < snowLines.size(); i = i+2) {
//			snowZones.add(j, new ArrayList<Double>()); //.add(snowLines.get(i)));
//			snowZones.get(j).add(snowLines.get(i));
//			snowZones.get(j).add(snowLines.get(i+1));
//			j++;
//		}
//		
//		System.out.println("YOU NEED TO FINISH LINES 766 AND 767!!!");
//		//if four snowZones, remove the 2nd one (to the left of the star)
//		//move last snowZone to the right of the star
//		
//		
//		
//		
//		
//		System.out.println("SnowZones: " + snowZones.size());
//		for (ArrayList<Double> snowLine: snowZones) {
//			System.out.println("Left side: " + snowLine.get(0));
//			System.out.println("Right side: " + snowLine.get(1));
//		}
//		
//		return snowZones;
	
	
		
//	}
	
	
	
	
	//Places stars into orbits, returns a list of MStarGroups for further calculations
//	private ArrayList<MStarGroup> createStarOrbits(MStarSystem thisSystem, ArrayList<MStar> stars) {
//		
//		EStarSystemType systemLayout = thisSystem.getSystemLayout();
//		
//		
//		if (systemLayout.equals(EStarSystemType.SINGLE)) {
//			stars.get(0).setOrbitalRadius(0.0); //star is at center of system
//			
//			MStarGroup starGroup = new MStarGroup();
//			starGroup.addStar(stars.get(0).getKey());
//			allGroups.add(starGroup);
//		}
//		else if (systemLayout.equals(EStarSystemType.BINARY_CENTER)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			
//			MStarGroup starGroup = new MStarGroup();
//			starGroup.addStar(stars.get(0).getKey());
//			starGroup.addStar(stars.get(1).getKey());
//			allGroups.add(starGroup);
//		}
//		else if (systemLayout.equals(EStarSystemType.BINARY_ORBIT)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			
//			double firstStarRadius = stars.get(0).getRadius();
//			double secondStarRadius = stars.get(1).getRadius();
//			
//			//Determine star orbital positions
//			double boundary1 = Constants.MinBinarySepKm + firstStarRadius + secondStarRadius;
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double secondStarDistance = rand.nextDouble()*(boundary2-boundary1)+boundary1;				
//			stars.get(1).setOrbitalRadius(secondStarDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			starGroup2.addStar(stars.get(1).getKey());
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_CENTER)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			stars.get(2).setOrbitalRadius(0.0);
//			
//			MStarGroup starGroup = new MStarGroup();
//			for (MStar star: stars) {
//				starGroup.addStar(star.getKey());
//			}			
//			allGroups.add(starGroup);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_BIN_CENTER_SIN_ORBIT)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius = largestRadius(tempSystem);
//			double thirdStarRadius = stars.get(2).getRadius();
//			
//			double boundary1 = Constants.MinBinarySepKm + largestRadius + thirdStarRadius;
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double thirdStarDistance = rand.nextDouble()*(boundary2-boundary1)+boundary1;			
//			stars.get(2).setOrbitalRadius(thirdStarDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			starGroup1.addStar(stars.get(1).getKey());
//			
//			starGroup2.addStar(stars.get(2).getKey());
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			
//			double firstStarRadius = stars.get(0).getRadius();
//			double secondStarRadius = stars.get(1).getRadius();
//			
//			double boundary1 = Constants.MinBinarySepKm + firstStarRadius + secondStarRadius;
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double binaryDistance = (rand.nextDouble()*(boundary2-boundary1)+boundary1);
//			stars.get(1).setOrbitalRadius(binaryDistance);
//			stars.get(2).setOrbitalRadius(binaryDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			
//			starGroup2.addStar(stars.get(1).getKey());
//			starGroup2.addStar(stars.get(2).getKey());
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_ALL_ORBIT)) {			
//			double firstStarRadius = stars.get(0).getRadius();
//			double secondStarRadius = stars.get(1).getRadius();
//			double thirdStarRadius = stars.get(2).getRadius();
//			
//			double firstStarDistance = 0.0;
//			stars.get(0).setOrbitalRadius(firstStarDistance);
//			
//			double boundary1 = Constants.MinBinarySepKm + firstStarRadius + secondStarRadius;
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double secondStarDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
//			stars.get(1).setOrbitalRadius(secondStarDistance);
//			
//			//Place 3rd star
//			//Bounds between 1st and 2nd stars
//			boundary1 = Constants.MinBinarySepKm + firstStarRadius + thirdStarRadius;
//			boundary2 = secondStarDistance - secondStarRadius - thirdStarRadius - Constants.MinBinarySepKm;
//			//Between 2nd star and edge of system
//			double boundary3 = secondStarDistance + secondStarRadius + thirdStarRadius + Constants.MinBinarySepKm;
//			double boundary4 = Constants.MaxBinarySepKm;
//			
//			double thirdStarDistance = rand.nextDouble()*(boundary4 - boundary1) + boundary1;
//			
//			while ((thirdStarDistance > boundary2) && (thirdStarDistance < boundary3)) {
//				thirdStarDistance = rand.nextDouble()*(boundary4 - boundary1) + boundary1;
//			}			
//			stars.get(2).setOrbitalRadius(thirdStarDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			MStarGroup starGroup3 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			starGroup2.addStar(stars.get(1).getKey());			
//			starGroup3.addStar(stars.get(2).getKey());
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);
//			allGroups.add(starGroup3);
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_CENTER)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			stars.get(2).setOrbitalRadius(0.0);
//			stars.get(3).setOrbitalRadius(0.0);
//			
//			MStarGroup starGroup = new MStarGroup();
//			for (MStar star: stars) {
//				starGroup.addStar(star.getKey());
//			}			
//			allGroups.add(starGroup);
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_TRI_CENTER_SINGLE_ORBIT)) {
//			
//			ArrayList<Integer> groups = new ArrayList<Integer>();
//			groups.add(systemLayout.getNumStarsGroup1());
//			groups.add(systemLayout.getNumStarsGroup2());
//			groups.add(systemLayout.getNumStarsGroup3());
//
//			//Remove zeros--no stars to place there.
//			ArrayList<Integer> garbage = new ArrayList<Integer>();
//			for (int i = 0; i < groups.size(); i++) {
//				if (groups.get(i) == 0) {
//					garbage.add(groups.get(i));
//				}
//			}
//			groups.removeAll(garbage);
//
//			ArrayList<MStarGroup> starGroups = new ArrayList<MStarGroup>();
//
//			double separationScale = 1.0;
//			if (systemLayout.getNumGroups() == 3) {
//				separationScale = 0.9;//keep down to 90% of max separation, to allow room for 3rd starGroup
//			}
//
//			int k = 0; //tracks location in stars List
//			
//			//Iterate over groups.  "i" tracks location among starGroups
//			for (int i = 0; i < groups.size(); i++) {
//				MStarGroup tempGroup = new MStarGroup();
//				starGroups.add(i, tempGroup);
//
//				//if first group in system:
//				if (i == 0) {
//					//Iterate over stars in group, adding each at a set 0.0 distance
//					for (int m = 0; m < groups.get(i); m++) {
//						stars.get(k).setOrbitalRadius(0.0);
//						starGroups.get(i).addStar(stars.get(k));
//						k++;
//					}
//				}
//				//if not first group in system:
//				else {
//					int kStart = k;
//
//					//Iterate over stars in group, adding each
//					for (int m = 0; m < groups.get(m); m++) {
//						starGroups.get(i).addStar(stars.get(k));
//						k++;
//					}
//
//					double prevGroupOrbit = starGroups.get(i-1).getOrbitalRadius();
//					double prevGroupRadius = starGroups.get(i-1).getTotalRadius();
//					double thisGroupRadius = starGroups.get(i).getTotalRadius();
//
//					//Set orbital radius of stars in group
//					double boundary1 = prevGroupOrbit + prevGroupRadius + Constants.MinBinarySepKm + thisGroupRadius;
//					double boundary2 = Constants.MaxBinarySepKm*separationScale;
//					
//					//Distance of this starGroup from last starGroup
//					double groupDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
//					
//					//Iterate over stars, setting orbitalRadius.  starGroups automatically updated.
//					for (int m = kStart; m < kStart + groups.get(m); m++) {
//						stars.get(m).setOrbitalRadius(groupDistance);
//					}					
//				}
//			}			
//			allGroups.addAll(starGroups);
	
	
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			MStarGroup starGroup3 = new MStarGroup();
//			int k = 0;
//			for (int j = 0; j < systemLayout.getNumStarsGroup1(); j++) {
//				stars.get(k).setOrbitalRadius(0.0);
//				starGroup1.addStar(stars.get(k));					
//				k++;
//			}
//				
//			double boundary1 = Constants.MinBinarySepKm + starGroup1.getTotalRadius() + stars.get(k+1).getRadius();
//			double boundary2 = Constants.MaxBinarySepKm*0.9; //keep down to 90% of max separation, to allow room for 4th star
//				
//				
//			for (int j = 0; j < systemLayout.getNumStarsGroup2(); j++) {
//				
//				k++;
//			}
//				
//			for (int j = 0; j < systemLayout.getNumStarsGroup3(); j++) {
//				k++;
//			}
//				
//				
//			//}
//			
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			stars.get(2).setOrbitalRadius(0.0);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			starGroup1.addStar(stars.get(0));
//			starGroup1.addStar(stars.get(1));			
//			starGroup1.addStar(stars.get(2));
//			
//			MStarGroup starGroup2 = new MStarGroup();
//			starGroup2.addStar(stars.get(3));
//			
//			double fullRadius = starGroup1.getTotalRadius();
//			
//			
//			//only send in the first three stars to determine largest radius
//			//ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			//tempSystem.add(stars.get(0));
//			//tempSystem.add(stars.get(1));
//			//tempSystem.add(stars.get(2));
//			//double largestRadius = largestRadius(tempSystem);
//			
//			//assume largest radius is in the center grouping
//			double boundary1 = Constants.MinBinarySepKm + fullRadius + stars.get(3).getRadius();
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double fourthStarDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
//			stars.get(3).setOrbitalRadius(fourthStarDistance);
//			
//			
//			
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);					
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_BIN_CENTER_BIN_ORBIT)) {
//			stars.get(0).setOrbitalRadius(0.0);
//			stars.get(1).setOrbitalRadius(0.0);
//			
//			//send in the stars from the FIRST binary pair to determine largest radius
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius1 = largestRadius(tempSystem);
//			
//			tempSystem.clear();
//			
//			//send in the stars from the second binary pair to determine their largest radius
//			tempSystem.add(stars.get(2));
//			tempSystem.add(stars.get(3));
//			double largestRadius2 = largestRadius(tempSystem);
//			
//			double boundary1 = Constants.MinBinarySepKm + largestRadius1 + largestRadius2;
//			double boundary2 = Constants.MaxBinarySepKm;
//			
//			double outerPairDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
//			
//			stars.get(2).setOrbitalRadius(outerPairDistance);
//			stars.get(3).setOrbitalRadius(outerPairDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			starGroup1.addStar(stars.get(1).getKey());			
//			starGroup2.addStar(stars.get(2).getKey());
//			starGroup2.addStar(stars.get(3).getKey());
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);			
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_BIN_CENTER_SIN_ORBIT_SIN_ORBIT)) {
//			double thirdStarRadius = stars.get(2).getRadius();
//			double fourthStarRadius = stars.get(3).getRadius();
//			
//			double firstStarDistance = 0.0;
//			stars.get(0).setOrbitalRadius(firstStarDistance);
//			stars.get(1).setOrbitalRadius(firstStarDistance);
//			
//			//send in the stars from the FIRST binary pair to determine largest radius
//			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
//			tempSystem.add(stars.get(0));
//			tempSystem.add(stars.get(1));
//			double largestRadius = largestRadius(tempSystem);
//			
//			double boundary1 = Constants.MinBinarySepKm + largestRadius + thirdStarRadius;
//			double boundary2 = Constants.MaxBinarySepKm*0.9; //keep down to 90% of max separation, to allow room for 4th star
//			
//			double thirdStarDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
//			stars.get(2).setOrbitalRadius(thirdStarDistance);
//			
//			//Place final star
//			//Bounds between 1st and 2nd stars
//			boundary1 = Constants.MinBinarySepKm + largestRadius + fourthStarRadius;
//			boundary2 = thirdStarDistance - thirdStarRadius - fourthStarRadius - Constants.MinBinarySepKm;
//			//Between 2nd star and edge of system
//			double boundary3 = thirdStarDistance + thirdStarRadius + fourthStarRadius + Constants.MinBinarySepKm;
//			double boundary4 = Constants.MaxBinarySepKm;
//			
//			double fourthStarDistance = rand.nextDouble()*(boundary4 - boundary3) + boundary3;
//			
//			while ((fourthStarDistance > boundary2) && (fourthStarDistance < boundary3)) {
//				fourthStarDistance = rand.nextDouble()*(boundary4 - boundary3) + boundary3;
//			}
//			
//			stars.get(3).setOrbitalRadius(fourthStarDistance);
//			
//			MStarGroup starGroup1 = new MStarGroup();
//			MStarGroup starGroup2 = new MStarGroup();
//			MStarGroup starGroup3 = new MStarGroup();
//			starGroup1.addStar(stars.get(0).getKey());
//			starGroup1.addStar(stars.get(1).getKey());			
//			starGroup2.addStar(stars.get(2).getKey());
//			starGroup3.addStar(stars.get(3).getKey());
//			
//			allGroups.add(starGroup1);
//			allGroups.add(starGroup2);
//			allGroups.add(starGroup3);
//		}
//		return allGroups;
//	}
	
	private ArrayList<StarGroupModel> createStarGroupOrbits(EStarSystemType systemType, ArrayList<StarModel> stars) {
		ArrayList<StarGroupModel> allGroups = new ArrayList<StarGroupModel>();
		
		ArrayList<Integer> groups = new ArrayList<Integer>();		
		groups.add(systemType.getNumStarsGroup1());
		groups.add(systemType.getNumStarsGroup2());
		groups.add(systemType.getNumStarsGroup3());

		//Remove zeros--no stars to place there.
		ArrayList<Integer> garbage = new ArrayList<Integer>();
		for (int i = 0; i < groups.size(); i++) {
			if (groups.get(i) == 0) {
				garbage.add(groups.get(i));
			}
		}
		groups.removeAll(garbage);

		ArrayList<StarGroupModel> starGroups = new ArrayList<StarGroupModel>();

		double separationScale = 1.0;
		if (systemType.getNumGroups() == 3) {
			separationScale = 0.9;//keep down to 90% of max separation, to allow room for 3rd starGroup
		}

		int k = 0; //tracks location in stars List
		
		//Iterate over groups.  "i" tracks location among starGroups
		for (int i = 0; i < groups.size(); i++) {
			//System.out.println("BatchSystemBuilder, createStarGroupOrbits i= " + i);
			StarGroupModel tempGroup = new StarGroupModel();
			starGroups.add(i, tempGroup);

			//if first group in system:
			if (i == 0) {
				//Iterate over stars in group, adding each at a set 0.0 distance
				for (int m = 0; m < groups.get(i); m++) {
					//System.out.println("BatchSystemBuilder, createStarGroupOrbits m= " + m);
					//System.out.println("BatchSystemBuilder, createStarGroupOrbits k= " + k);
					stars.get(k).setOrbitalRadius(0.0);
					//System.out.println("BatchSystemBuilder, createStarGroupOrbits radiusSet");
					//System.out.println("BatchSystemBuilder, starType: " + stars.get(k).getType().toString());
					starGroups.get(i).addStar(stars.get(k));
					//System.out.println("BatchSystemBuilder, createStarGroupOrbits starAdded");
					k++;
					//System.out.println("BatchSystemBuilder, createStarGroupOrbits next k= " + k);
				}
			}
			//if not first group in system:
			else {
				int kStart = k;
				
				//System.out.println("BatchSystemBuilder, createStarGroupOrbits 2nd i= " + i);
				
				//Iterate over stars in group, adding each
				for (int m = 0; m < groups.get(i); m++) {					
					starGroups.get(i).addStar(stars.get(k));
					k++;
				}

				double prevGroupOrbit = starGroups.get(i-1).getOrbitalRadius();
				double prevGroupRadius = starGroups.get(i-1).getTotalRadius();
				double thisGroupRadius = starGroups.get(i).getTotalRadius();

				//Set orbital radius of stars in group
				double boundary1 = prevGroupOrbit + prevGroupRadius + Constants.MinBinarySepKm + thisGroupRadius;
				double boundary2 = Constants.MaxBinarySepKm*separationScale;
				
				//Distance of this starGroup from last starGroup
				double groupDistance = rand.nextDouble()*(boundary2 - boundary1) + boundary1;
				
				//System.out.println("L1592 kStart: " + kStart);
				//System.out.println("Stars size: " + stars.size());
				//System.out.println("Groups size: " + groups.size());
				
				//Iterate over stars, setting orbitalRadius.  starGroups automatically updated.
				for (int m = kStart; m < kStart + groups.get(i); m++) {
					stars.get(m).setOrbitalRadius(groupDistance);
				}					
			}
		}			
		allGroups.addAll(starGroups);
		
		return allGroups;
	}
	
//	private ArrayList<ArrayList<Double>> setHabZones(MStarSystem thisSystem, ArrayList<MStarGroup> starGroups) {
//		//Find gravitational zero points between stars to determine allowable orbit zones.
//		//ArrayList<Double> gravZeroPoints = new ArrayList<Double>();
//		ArrayList<ArrayList<Double>> allowedOrbitZoneBounds = new ArrayList<ArrayList<Double>>();
//		
//		//ArrayList<MStarGroup> starGroups = thisSystem.getStarGroups();
//		EStarSystemType systemLayout = thisSystem.getSystemLayout();
//		
//		for (int i = 0; i < systemLayout.getNumGroups()-1; i++) {
//			adjustHabZones(starGroups.get(i), starGroups.get(i+1));			
//		}
//		
//		int j = 0;
//		for (MStarGroup starGroup: starGroups) {
//			allowedOrbitZoneBounds.add(j, new ArrayList<Double>());
//			allowedOrbitZoneBounds.get(j).addAll(starGroup.getHabZoneList());
//			j++;
//		}
//		
//		
//		//Current strategy:  Place the stars into systemLayout according to mass
//		if (systemLayout.equals(EStarSystemType.SINGLE)) {
//			//DO NOTHING.  MSTARGROUP calculates automatically.  REMOVE THIS SECTION
//			
//			//double firstStarRadius = stars.get(0).getRadiusList();
//			//gravZeroPoints.add(0.0);
//			
//			//double innerBound = Constants.MinHabOrbitKm+firstStarRadius;
//			//double outerBound = Constants.MaxHabOrbitKm;
//			//allowedOrbitZoneBounds.add(new ArrayList<Double>());
//			//allowedOrbitZoneBounds.get(0).add(innerBound);
//			//allowedOrbitZoneBounds.get(0).add(outerBound);
//		}
//		else if (systemLayout.equals(EStarSystemType.BINARY_CENTER)) {
//			//DO NOTHING.  MSTARGROUP calculates automatically.  REMOVE THIS SECTION
//			
////			gravZeroPoints.add(0.0);
////			
////			double largestRadius = largestRadius(stars);
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double innerBound = Constants.MinHabOrbitKm+largestRadius;
////			double outerBound = Constants.MaxHabOrbitKm;				
////			allowedOrbitZoneBounds.get(0).add(innerBound);
////			allowedOrbitZoneBounds.get(0).add(outerBound);
//		}
//		else if (systemLayout.equals(EStarSystemType.BINARY_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			
////			double firstStarRadius = stars.get(0).getRadiusList();
////			double secondStarRadius = stars.get(1).getRadiusList();
////			
////			double secondStarDistance = stars.get(1).getOrbitRadius();
////			
////			//Determine allowable orbit zones around each star
////			/*
////			 * Each allowable zone is determined by calculating the gravitational zero point (where grav.
////			 * forces in 1D from each star cancel) and then taking some distance from that point as 
////			 * "not allowed."  This distance is currently a weighted average on each side of the zero point,
////			 * using the masses on each side for weighting
////			 */
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double totalMass = mass1 + mass2;
////			double massTerm = Math.sqrt(mass1/mass2);
////			double gravZeroPoint =  secondStarDistance*massTerm/(1+massTerm);
////			gravZeroPoints.add(gravZeroPoint);
////			
////			double r1 = gravZeroPoint; //distance from first star to zero point
////			double r2 = secondStarDistance - gravZeroPoint; //dist from zero point to second star
////			
////			//allowable zone, closer to first star
////			double innerBound1 = Constants.MinHabOrbitKm+firstStarRadius;
////			double outerBound1 = r1*mass1/totalMass;
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable zone, closer to second star
////			double innerBound2 = r1 + r2*(1-mass2/totalMass);
////			double outerBound2 = secondStarDistance - secondStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_CENTER)) {
//			//DO NOTHING.  MStarGroup handles this.  DELETE THIS SECTION.
//			
////			gravZeroPoints.add(0.0);
////			
////			double largestRadius = largestRadius(stars);
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double innerBound =	Constants.MinHabOrbitKm + largestRadius;
////			double outerBound = Constants.MaxHabOrbitKm;				
////			allowedOrbitZoneBounds.get(0).add(innerBound);
////			allowedOrbitZoneBounds.get(0).add(outerBound);
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_BIN_CENTER_SIN_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(0));
////			tempSystem.add(stars.get(1));
////			double largestRadius = largestRadius(tempSystem);				
////						
////			double thirdStarDistance = stars.get(2).getOrbitRadius();
////			double thirdStarRadius = stars.get(2).getRadiusList();
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();
////			double totalMass = mass1+mass2+mass3;
////			double binaryMass = mass1+mass2;
////			double massTerm = Math.sqrt(binaryMass/mass3);
////			double gravZeroPoint = thirdStarDistance*massTerm/(1+massTerm);				
////			gravZeroPoints.add(gravZeroPoint);
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double r1 = gravZeroPoint;
////			double r2 = thirdStarDistance - gravZeroPoint;
////			
////			//allowable zone closer to first star group
////			double innerBound1 = Constants.MinHabOrbitKm+largestRadius;
////			double outerBound1 = r1*binaryMass/totalMass;					
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable zone closer to orbiting star
////			double innerBound2 = r1 + r2*(1-mass3/totalMass);
////			double outerBound2 = thirdStarDistance - thirdStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);			
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_SIN_CENTER_BIN_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(1));
////			tempSystem.add(stars.get(2));
////			double largestRadius = largestRadius(tempSystem);	
////			
////			double firstStarRadius = stars.get(0).getRadiusList();
////			double binaryDistance = stars.get(1).getOrbitRadius();
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();
////			double totalMass = mass1 + mass2 + mass3;
////			double binaryMass = mass2 + mass3;
////			double massTerm = Math.sqrt(mass1/binaryMass);
////			double gravZeroPoint =  binaryDistance*massTerm/(1+massTerm);				
////			gravZeroPoints.add(gravZeroPoint);				
////			
////			double r1 = gravZeroPoint;
////			double r2 = binaryDistance - gravZeroPoint;
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			//allowable zone closer to first star				
////			double innerBound1 = Constants.MinHabOrbitKm+firstStarRadius;
////			double outerBound1 = r1*mass1/totalMass;
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable zone closer to binary star group
////			double innerBound2 = r1 + r2*(1-binaryMass/totalMass);
////			double outerBound2 = binaryDistance - largestRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);				
//		}
//		else if (systemLayout.equals(EStarSystemType.TRINARY_ALL_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			adjustHabZones(starGroups.get(1), starGroups.get(2));
//			
////			double firstStarRadius = stars.get(0).getRadiusList();
////			double secondStarRadius = stars.get(1).getRadiusList();
////			double thirdStarRadius = stars.get(2).getRadiusList();
////			
////			double secondStarDistance = stars.get(1).getOrbitRadius();
////			double thirdStarDistance = stars.get(2).getOrbitRadius();
////			
////			//Ignore the third star when calculating zero gravity point between 1st and 2nd
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();				
////			double massTerm = Math.sqrt(mass1/mass2);
////			double gravZeroPoint = secondStarDistance*massTerm/(1+massTerm);
////			gravZeroPoints.add(gravZeroPoint);
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double r11 = gravZeroPoint;
////			double r21 = secondStarDistance - gravZeroPoint;
////			
////			massTerm = Math.sqrt(mass2/mass3);
////			gravZeroPoint = (thirdStarDistance - secondStarDistance)*massTerm/(1+massTerm);
////			gravZeroPoints.add(gravZeroPoint);
////			
////			double r12 = gravZeroPoint;// - secondStarDistance;
////			double r22 = (thirdStarDistance - secondStarDistance) - gravZeroPoint;
////			
////			//allowable orbital zone between 1st and 2nd stars, near 1st star
////			double innerBound1 = Constants.MinHabOrbitKm + firstStarRadius;
////			double outerBound1 = r11*mass1/(mass1+mass2);
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable orbital zone between 1st and 2nd stars, near 2nd star
////			double innerBound2 = r11 + r21*(1-mass2/(mass1+mass2));
////			double outerBound2 = secondStarDistance - secondStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);
////			
////			//allowable orbital zone between 2nd and 3rd stars, near 2nd star
////			double innerBound3 = secondStarDistance + secondStarRadius + Constants.MinHabOrbitKm;
////			double outerBound3 = secondStarDistance + r12*mass2/(mass2+mass3);
////			allowedOrbitZoneBounds.get(2).add(innerBound3);
////			allowedOrbitZoneBounds.get(2).add(outerBound3);
////			
////			//allowable orbital zone between 2nd and 3rd stars, near 3rd star
////			double innerBound4 = secondStarDistance + r12 + r22*(1-mass3/(mass2+mass3));
////			double outerBound4 = thirdStarDistance - thirdStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(3).add(innerBound4);
////			allowedOrbitZoneBounds.get(3).add(outerBound4);
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_CENTER)) {
//			//DO NOTHING.  MStarGroup takes care of this.  DELETE THIS SECTIOn
//			
////			double largestRadius = largestRadius(stars);
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double innerBound = largestRadius + Constants.MinHabOrbitKm;
////			double outerBound = Constants.MaxHabOrbitKm;
////			allowedOrbitZoneBounds.get(0).add(innerBound);
////			allowedOrbitZoneBounds.get(0).add(outerBound);
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_TRI_CENTER_SINGLE_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));			
//			
////			//only send in the first three stars to determine largest radius
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(0));
////			tempSystem.add(stars.get(1));
////			tempSystem.add(stars.get(2));
////			double largestRadius = largestRadius(tempSystem);
////			
////			double fourthStarDistance = stars.get(3).getOrbitRadius();			
////			double fourthStarRadius = stars.get(3).getRadiusList();
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();
////			double mass4 = stars.get(2).getMassList();
////			double totalMass = mass1 + mass2 + mass3 + mass4;
////			double trinaryMass = mass1 + mass2 + mass3;
////			double massTerm = Math.sqrt(trinaryMass/mass4);
////			double gravZeroPoint = fourthStarDistance*massTerm/(1+massTerm);				
////			gravZeroPoints.add(gravZeroPoint);				
////			
////			double r1 = gravZeroPoint;
////			double r2 = fourthStarDistance - gravZeroPoint;
////			
////			//allowable zone closer to trinary star group				
////			double innerBound1 = Constants.MinHabOrbitKm+largestRadius;
////			double outerBound1 = r1*trinaryMass/totalMass;
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable zone closer to single star
////			double innerBound2 = r1 + r2*(1-mass4/totalMass);
////			double outerBound2 = fourthStarDistance - fourthStarRadius - Constants.MinHabOrbitKm;				
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);			
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_BIN_CENTER_BIN_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			
////			//send in the stars from the FIRST binary pair to determine largest radius
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(0));
////			tempSystem.add(stars.get(1));
////			double largestRadius1 = largestRadius(tempSystem);
////			
////			tempSystem.clear();
////			
////			//send in the stars from the second binary pair to determine their largest radius
////			tempSystem.add(stars.get(2));
////			tempSystem.add(stars.get(3));
////			double largestRadius2 = largestRadius(tempSystem);
////			
////			double outerPairDistance = stars.get(2).getOrbitRadius();
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();
////			double mass4 = stars.get(2).getMassList();
////			double totalMass = mass1 + mass2 + mass3 + mass4;
////			double binaryMass1 = mass1+mass2;
////			double binaryMass2 = mass3+mass4;
////			
////			double massTerm = Math.sqrt(binaryMass1/binaryMass2);
////			double gravZeroPoint = outerPairDistance*massTerm/(1+massTerm);				
////			gravZeroPoints.add(gravZeroPoint);				
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double r1 = gravZeroPoint;
////			double r2 = outerPairDistance - gravZeroPoint;
////			
////			//allowable orbit zone closer to first binary
////			double innerBound1 = largestRadius1 + Constants.MinHabOrbitKm;
////			double outerBound1 = r1*binaryMass1/totalMass;
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable orbit zone closer to second binary
////			double innerBound2 = r1 + r2*(1-binaryMass2/totalMass);
////			double outerBound2 = outerPairDistance - largestRadius2 - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);
//		}
//		else if (systemLayout.equals(EStarSystemType.QUAD_BIN_CENTER_SIN_ORBIT_SIN_ORBIT)) {
//			adjustHabZones(starGroups.get(0), starGroups.get(1));
//			adjustHabZones(starGroups.get(1), starGroups.get(2));
//			
////			double thirdStarRadius = stars.get(2).getRadiusList();
////			double fourthStarRadius = stars.get(3).getRadiusList();
////			
////			//send in the stars from the FIRST binary pair to determine largest radius
////			ArrayList<MStar> tempSystem = new ArrayList<MStar>();
////			tempSystem.add(stars.get(0));
////			tempSystem.add(stars.get(1));
////			double largestRadius = largestRadius(tempSystem);
////			
////			double thirdStarDistance = stars.get(2).getOrbitRadius();			
////			double fourthStarDistance = stars.get(3).getOrbitRadius();
////			
////			double mass1 = stars.get(0).getMassList();
////			double mass2 = stars.get(1).getMassList();
////			double mass3 = stars.get(2).getMassList();
////			double mass4 = stars.get(2).getMassList();
////			double totalMass = mass1 + mass2 + mass3 + mass4;
////			double binaryMass = mass1+mass2;
////							
////			//ignore fourth star when determining gravity zero point
////			double massTerm = Math.sqrt(binaryMass/mass3);
////			double gravZeroPoint = thirdStarDistance*massTerm/(1+massTerm);				
////			gravZeroPoints.add(gravZeroPoint);
////			
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			allowedOrbitZoneBounds.add(new ArrayList<Double>());
////			
////			double r11 = gravZeroPoint;
////			double r21 = thirdStarDistance - gravZeroPoint;
////			
////			massTerm = Math.sqrt(mass3/mass4);
////			gravZeroPoint = (fourthStarDistance-thirdStarDistance)*massTerm/(1+massTerm);
////			gravZeroPoints.add(gravZeroPoint);
////			
////			double r12 = gravZeroPoint;// + thirdStarDistance;
////			double r22 = (fourthStarDistance-thirdStarDistance) - gravZeroPoint;
////			
////			//allowable orbital zone between binary and 3rd star, near binary
////			double innerBound1 = largestRadius + Constants.MinHabOrbitKm;
////			double outerBound1 = r11*binaryMass/(binaryMass+mass3);
////			allowedOrbitZoneBounds.get(0).add(innerBound1);
////			allowedOrbitZoneBounds.get(0).add(outerBound1);
////			
////			//allowable orbital zone between binary and 3rd star, near 3rd star
////			double innerBound2 = r11 + r21*(1-mass3/binaryMass);
////			double outerBound2 = thirdStarDistance - thirdStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(1).add(innerBound2);
////			allowedOrbitZoneBounds.get(1).add(outerBound2);
////			
////			//allowable orbital zone between 3rd and 4th stars, near 3rd star
////			double innerBound3 = thirdStarDistance + thirdStarRadius + Constants.MinHabOrbitKm;
////			double outerBound3 = thirdStarDistance + r12*mass3/(mass3+mass4);
////			allowedOrbitZoneBounds.get(2).add(innerBound3);
////			allowedOrbitZoneBounds.get(2).add(outerBound3);
////			
////			//allowable orbital zone between 3rd and 4th stars, near 4th star
////			double innerBound4 = thirdStarDistance + r12 + r22*(1-mass4/(mass3+mass4));
////			double outerBound4 = fourthStarDistance - fourthStarRadius - Constants.MinHabOrbitKm;
////			allowedOrbitZoneBounds.get(3).add(innerBound4);
////			allowedOrbitZoneBounds.get(3).add(outerBound4);
//		}
//		System.out.println("System Type: " + thisSystem.getSystemLayout().toString());
//		
////		for (MStar star: stars) {
////			System.out.println("Orbit dist: " + star.getOrbitRadius());
////		}
//		
////		System.out.println("Number of pairs: " + allowedOrbitZoneBounds.size());
////		for (ArrayList<Double> boundPair: allowedOrbitZoneBounds) {
////			System.out.println("Left: " + boundPair.get(0));
////			System.out.println("Right: " + boundPair.get(1));
////		}
////		System.out.println("Removing reflected negative pairs...");
////		/*
////		 * If there are four zones (three groupings of stars), check if either of the inner zones (index 1 and 2)
////		 * is negative--innerbound greater than outerbound, so no orbits can exist there.  If either one is negative,
////		 * then remove orbits on both sides of the star
////		 */
////		if (allowedOrbitZoneBounds.size() == 4) {
////			if (
////					(allowedOrbitZoneBounds.get(1).get(0) > allowedOrbitZoneBounds.get(1).get(1))
////					||
////					(allowedOrbitZoneBounds.get(2).get(0) > allowedOrbitZoneBounds.get(2).get(1))
////				)
////			{
////				allowedOrbitZoneBounds.remove(2);
////				allowedOrbitZoneBounds.remove(1);					
////			}				
////		}
////		
////		System.out.println("Number of pairs: " + allowedOrbitZoneBounds.size());
////		for (ArrayList<Double> boundPair: allowedOrbitZoneBounds) {
////			System.out.println("Left: " + boundPair.get(0));
////			System.out.println("Right: " + boundPair.get(1));
////		}
////		
////		
////		System.out.println("Removing any additional negative pairs");
////		//Check all remaining zones and remove any that are negative (innerbound greater than outerBound)
////		ArrayList<ArrayList<Double>> garbageCollection = new ArrayList<ArrayList<Double>>();//allowedOrbitZoneBounds;
////		for (ArrayList<Double> allowedRange : allowedOrbitZoneBounds) {
////			if (allowedRange.get(0) > allowedRange.get(1)) {
////				garbageCollection.add(allowedRange);
////			}
////		}
////		allowedOrbitZoneBounds.removeAll(garbageCollection);
////		
////		System.out.println("Number of pairs: " + allowedOrbitZoneBounds.size());
////		for (ArrayList<Double> boundPair: allowedOrbitZoneBounds) {
////			System.out.println("Left: " + boundPair.get(0));
////			System.out.println("Right: " + boundPair.get(1));
////		}
////		
////		System.out.println("Removing any uneven zones around center star/grouping");
////		/*
////		 * Possibility for uneven zones around the center star/grouping when there are 3 separate groupings
////		 * Second zone, third zone (left, right of star/group) should be equidistant from star/group center
////		 * Shrink whichever zone is larger.  Planets can't orbit around just half of a star!
////		 */
////		if (allowedOrbitZoneBounds.size() == 4) {
////			ArrayList<Double> leftSide = allowedOrbitZoneBounds.get(1);
////			ArrayList<Double> rightSide = allowedOrbitZoneBounds.get(2);
////			if ((leftSide.get(1) - leftSide.get(0)) > (rightSide.get(1) - rightSide.get(0))) {
////				double adjustment = leftSide.get(1) - (rightSide.get(1) - rightSide.get(0));
////				allowedOrbitZoneBounds.get(1).set(0, adjustment);										
////			}
////			else {
////				double adjustment = rightSide.get(0) + (leftSide.get(1) - leftSide.get(0));
////				allowedOrbitZoneBounds.get(2).set(1, adjustment);					
////			}
////		}
////		
////		System.out.println("Number of pairs: " + allowedOrbitZoneBounds.size());
////		for (ArrayList<Double> boundPair: allowedOrbitZoneBounds) {
////			System.out.println("Left: " + boundPair.get(0));
////			System.out.println("Right: " + boundPair.get(1));
////		}
////		
////		/*
////		 * If more than one pair of habZones remain, either take out the 2nd one, to the left of the star or
////		 * move last pair to the right side of the last star, so now all habZones are oriented the
////		 * same way 
////		 */
////		MStar thisStar;
////		ArrayList<Double> thisHabZone;
////		double leftOuterBound;
////		double rightOuterBound;
////		garbageCollection.clear();
////		
////		System.out.println("stars.size(): " + stars.size());
////		int i = 0;
////		for (ArrayList<Double> habZone: allowedOrbitZoneBounds) {
////			
////			
////		}
////		for (int i = 0; i < stars.size(); i++) {
////			thisStar = stars.get(i);
////			thisHabZone = allowedOrbitZoneBounds.get(i);
////			
////			if (thisHabZone.get(0) < thisStar.getOrbitRadius()) {
////				//habZone is to the left of the star.
////				if (i == stars.size() - 1) {
////					//last star, so do not delete but move habZone over to the right
////					leftOuterBound = (thisStar.getOrbitRadius() - thisHabZone.get(1)) + thisStar.getOrbitRadius();
////					rightOuterBound = (thisHabZone.get(1) - thisHabZone.get(0)) + thisStar.getOrbitRadius() + (thisStar.getOrbitRadius() - thisHabZone.get(1));					
////					
////					allowedOrbitZoneBounds.get(i).set(0, leftOuterBound);
////					allowedOrbitZoneBounds.get(i).set(1, rightOuterBound);
////				}
////				else {
////					//not last star, so just delete these values--they are mirrored by value to the right					
////					garbageCollection.add(allowedOrbitZoneBounds.get(i));
////				}
////			}
////		}
////		
////		//delete tempCollection from allowedOrbitZoneBounds
////		allowedOrbitZoneBounds.removeAll(garbageCollection);
//		
//		System.out.println("Final habZones");
//		for (MStarGroup starGroup: starGroups) {
//			System.out.println("Left: " + starGroup.getHabZoneList().get(0));
//			System.out.println("Right: " + starGroup.getHabZoneList().get(1));
//		}
//		
////		for (ArrayList<Double> boundPair: allowedOrbitZoneBounds) {
////			System.out.println("Left: " + boundPair.get(0));
////			System.out.println("Right: " + boundPair.get(1));
////		}
//		
//		System.out.println("DONE");
//		System.out.println("");		
//		
//		return allowedOrbitZoneBounds;
//	}
	
//	private void adjustHabZones(MStarGroup group1, MStarGroup group2) {
//		ArrayList<Double> gravZeroPoints = new ArrayList<Double>();
//		
//		double radius1 = group1.getTotalRadius();
//		double radius2 = group2.getTotalRadius();
//		
//		//Shift orbits to center around 0 point
//		double orbit1 = 0.0;
//		double orbit2 = group2.getOrbitalRadius() - group1.getOrbitalRadius();			
//		
//		double mass1 = group1.getTotalMass();
//		double mass2 = group2.getTotalMass();			
//		double combinedMass = mass1 + mass2;
//		
//		double massTerm = Math.sqrt(mass1/mass2);
//		double gravZeroPoint = orbit2*massTerm/(1+massTerm);
//		gravZeroPoints.add(gravZeroPoint);
//		
//		double r1 = gravZeroPoint - orbit1;
//		double r2 = orbit2 - gravZeroPoint;
//		
//		//inner, outer bounds of habZone around group1
//		double innerBound1 = group1.getHabZoneList().get(0);
//		double outerBound1 = r1*mass1/combinedMass;
//		//inner, outer bounds of habZone around group2
//		double innerBound2 = group2.getHabZoneList().get(0);
//		double outerBound2 = r2*mass2/combinedMass;
//		
//		if (innerBound1 > outerBound1) {
//			group1.getHabZoneList().clear();
//			//group1.getHabZoneList().set(1, 0.0);
//		}			
//		else if (outerBound1 < group1.getHabZoneList().get(1)) {
//			group1.getHabZoneList().set(1, outerBound1);
//		}
//		
//		if (innerBound2 > outerBound2) {
//			group2.getHabZoneList().clear();
//		}			
//		else if (outerBound2 < group2.getHabZoneList().get(1)) {
//			group2.getHabZoneList().set(1, outerBound2);
//		}
//	}
	
//	private double largestRadius(ArrayList<MStar> thisSystem) {
//		
//		double largestRadius = 0.0;
//		double radius = 0.0;
//		for (MStar star: thisSystem) {
//			radius = star.getRadius();
//			if (radius > largestRadius)
//				largestRadius = radius;			
//		}		
//		
//		return largestRadius;
//	}

//	private void addStar(MStar star, int index) {
//		
//		EStarType type = star.getType();
//				
//		buildStar(settings.getGalaxyAge());
//				
//		starModels.get(index).add(starModel);
//		starViews.get(index).add(starView);
//		starControllers.get(index).add(starController);
//		
////		//Create mandatory companions
////		for (int j = 0; j < mandatory.size(); j++) {
////			buildStar(mandatory.get(j)); //updates starModel, etc. variable with a new star
////			starModels.get(index).add(starModel);
////			starViews.get(index).add(starView);
////			starControllers.get(index).add(starController);			
////		}
////		//Create remaining companions
////		for (int i = 0; i < (numStars-mandatory.size()); i++) {
////			buildStar(settings.getGalaxyAge()); //updates starModel, etc. variable
////			starModels.get(index).add(starModel);
////			starViews.get(index).add(starView);
////			starControllers.get(index).add(starController);			
////		}
//	}
	
	
//	private void buildStar(EStarType type) {
//		//double temperature = randomTemperature(type);
//		
//		//starModel = starModelFact.createMStar(temperature, type);
//		//starView = starViewFact.createView(starModel, assets);
//		starController = new CStar(eventManager);
//	}
//	
//	private void buildStar(EGalaxyAge age) {
//		EStarType type = randomType(age);
//		double temperature = randomTemperature(type);
//		
//		starModel = starModelFact.createMStar(temperature, type);
//		starView = starViewFact.createView(starModel, assets);
//		starController = new CStar(eventManager);
//	}
		
	private EStarType randomType(EGalaxyAge age) {
		
		int column;
		int probIndex = -1;
		EStarType type = EStarType.BLACKHOLE; //default to Blackhole
		
		if (age.equals(EGalaxyAge.YOUNG))
			column = 0;
		else if (age.equals(EGalaxyAge.AVERAGE))
			column = 1;
		else
			column = 2;
		
		double value = rand.nextDouble();
		
		for (int i = 0; i < starTypes; i++)
		{
			if ((value - cumuStarTypeProbs[i][column]) >= 0)
			{
				probIndex = i; //leaves value at last index > 0
				type = EStarType.get(probIndex);					
			}				
		}		
		
		return type;
	}
	
	private double randomTemperature(EStarType type) {
		double maxTemp = type.getMaxTemp();
		double minTemp = type.getMinTemp();
		double tempRange = maxTemp - minTemp;
		double temperature = rand.nextDouble()*tempRange + minTemp;
		
		return temperature;
		
	}
	
	//computes cumulative probabilities for each star type given universe age
	private void calcStarTypeProbs(){
		int row = 0;
		
		double col0 = 0.0;
		double col1 = 0.0;
		double col2 = 0.0;
		
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.DWARF_WHITE.getYoungDist();
		col1 += EStarDistribution.DWARF_WHITE.getAvgDist();
		col2 += EStarDistribution.DWARF_WHITE.getOldDist();		
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_BLUE.getYoungDist();
		col1 += EStarDistribution.MS_BLUE.getAvgDist();
		col2 += EStarDistribution.MS_BLUE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_BLUEWHITE.getYoungDist();
		col1 += EStarDistribution.MS_BLUEWHITE.getAvgDist();
		col2 += EStarDistribution.MS_BLUEWHITE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_WHITE.getYoungDist();
		col1 += EStarDistribution.MS_WHITE.getAvgDist();
		col2 += EStarDistribution.MS_WHITE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_YELLOWWHITE.getYoungDist();
		col1 += EStarDistribution.MS_YELLOWWHITE.getAvgDist();
		col2 += EStarDistribution.MS_YELLOWWHITE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_YELLOW.getYoungDist();
		col1 += EStarDistribution.MS_YELLOW.getAvgDist();
		col2 += EStarDistribution.MS_YELLOW.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_ORANGE.getYoungDist();
		col1 += EStarDistribution.MS_ORANGE.getAvgDist();
		col2 += EStarDistribution.MS_ORANGE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.MS_RED.getYoungDist();
		col1 += EStarDistribution.MS_RED.getAvgDist();
		col2 += EStarDistribution.MS_RED.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.GIANT.getYoungDist();
		col1 += EStarDistribution.GIANT.getAvgDist();
		col2 += EStarDistribution.GIANT.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.SUPERGIANT.getYoungDist();
		col1 += EStarDistribution.SUPERGIANT.getAvgDist();
		col2 += EStarDistribution.SUPERGIANT.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.HYPERGIANT.getYoungDist();
		col1 += EStarDistribution.HYPERGIANT.getAvgDist();
		col2 += EStarDistribution.HYPERGIANT.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.NEUTRON.getYoungDist();
		col1 += EStarDistribution.NEUTRON.getAvgDist();
		col2 += EStarDistribution.NEUTRON.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
		
		col0 += EStarDistribution.BLACKHOLE.getYoungDist();
		col1 += EStarDistribution.BLACKHOLE.getAvgDist();
		col2 += EStarDistribution.BLACKHOLE.getOldDist();
		row++;
		cumuStarTypeProbs[row][0] = col0;
		cumuStarTypeProbs[row][1] = col1;
		cumuStarTypeProbs[row][2] = col2;
	}
	
	private void calcMultiStarProbs(EStarType type) {
		double value = 0.0;		
		cumuMultiStarProbs[0] = value;
		
		value+= type.getBinaryProb();
		cumuMultiStarProbs[1] = value;
		
		value += type.getTrinaryProb();
		cumuMultiStarProbs[2] = value;
		
		value += type.getQuadProb();
		cumuMultiStarProbs[3] = value;		
	}		
	
}
